<template>
  <div :style="{height:height+'px',zIndex:zIndex}">
    <div
      :class="className"
      :style="{top:(isSticky ? stickyTop +'px' : ''),zIndex:zIndex,position:position,width:width,height:height+'px'}"
    >
      <slot>
        <div>sticky</div>
      </slot>
    </div>
  </div>
</template>

<script>

export default {
  name: 'Sticky'
}
</script>

<script setup>
import { ref, defineProps, onMounted, onActivated, onUnmounted, getCurrentInstance } from 'vue'

const props = defineProps({
  stickyTop: {
    type: Number,
    default: 0
  },
  zIndex: {
    type: Number,
    default: 1
  },
  className: {
    type: String,
    default: ''
  }
})

const { ctx } = getCurrentInstance()

const active = ref(false)
const position = ref('')
const width = ref()
const height = ref()
const isSticky = ref(false)

onMounted(() => {
  height.value = ctx.$el.getBoundingClientRect().height
  window.addEventListener('scroll', handleScroll)
  window.addEventListener('resize', handleResize)
})

onActivated(() => {
  handleScroll()
})

onUnmounted(() => {
  window.removeEventListener('scroll', handleScroll)
  window.removeEventListener('resize', handleResize)
})

const sticky = () => {
  if (active.value) {
    return
  }
  position.value = 'fixed'
  active.value = true
  width.value = width.value + 'px'
  isSticky.value = true
}

const handleReset = e => {
  if (!active.value) {
    return
  }
  reset()
}

const reset = () => {
  position.value = ''
  width.value = 'auto'
  active.value = false
  isSticky.value = false
}

const handleScroll = () => {
  const width1 = ctx.$el.getBoundingClientRect().width
  width.value = width1 || 'auto'
  const offsetTop = ctx.$el.getBoundingClientRect().top
  if (offsetTop < props.stickyTop) {
    sticky()
    return
  }
  handleReset()
}

const handleResize = () => {
  if (isSticky.value) {
    width.value = ctx.$el.getBoundingClientRect().width + 'px'
  }
}
</script>
